
#include "aht20.h"
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_errno.h" //==IOT_SUCCESS =0 
#include <stddef.h>
#include <hi_time.h> 
#include <string.h>


#include <hi_i2c.h>
#include <hi_io.h>
#include <iot_gpio.h>

//使能i2c-0
void AHT20_I2C_Init(void)
{
    IoTGpioInit(AHT20_SDA);
    hi_io_set_func(AHT20_SDA,HI_IO_FUNC_GPIO_13_I2C0_SDA);
    IoTGpioInit(AHT20_SCL);  
    hi_io_set_func(AHT20_SCL,HI_IO_FUNC_GPIO_14_I2C0_SCL);
    hi_i2c_init(AHT20_I2C_IDX,AHT20_I2C_BAUDRATE); 
}

static uint32_t AHT20_Read(uint8_t *data, uint32_t dataLen)
{
  hi_i2c_idx id = AHT20_I2C_IDX;
  hi_i2c_data i2cData;
  i2cData.receive_buf = data;
  i2cData.receive_len = dataLen;
  i2cData.send_buf = NULL;
  i2cData.send_len = 0;
  uint32_t result;
  result = hi_i2c_read((hi_i2c_idx)id,AHT20_READ,&i2cData);
  if(result != IOT_SUCCESS){
    printf("AHT20_Read() Failed ,%0X\n",result);
    return result; }
  return IOT_SUCCESS ;
}

static uint32_t AHT20_Write(uint8_t *data, uint32_t dataLen)
{
  hi_i2c_idx id = AHT20_I2C_IDX;
  hi_i2c_data i2cData;
  i2cData.receive_buf = NULL;
  i2cData.receive_len = 0;
  i2cData.send_buf = data;
  i2cData.send_len = dataLen;
  uint32_t result;
  result = hi_i2c_write((hi_i2c_idx)id,AHT20_WRITE,&i2cData);
  if(result != IOT_SUCCESS){
    printf("AHT20_Write() Failed ,%0X\n",result);
    return result; }
  return IOT_SUCCESS ;
}

//获取状态
static uint32_t AHT20_Status(void)
{
  uint8_t statuscmd={AHT20_STATUS};
  return AHT20_Read(&statuscmd,sizeof(statuscmd));
}
//软复位
static uint32_t AHT20_Reset(void)
{
  uint8_t reset = {AHT20_RESET_CMD};
  return AHT20_Write(&reset,sizeof(reset));
}
//校准
static uint32_t AHT20_Initcmd(void)
{
  uint8_t initialcmd[] ={AHT20_INIT_CMD, AHT20_INIT_CMD_B1,AHT20_INIT_CMD_B2};
  return AHT20_Write(&initialcmd,sizeof(initialcmd));
}
//触发测量
uint32_t AHT20_StartMeasure(void)
{
  uint8_t startcmd[] ={AHT20_TRAG_CMD, AHT20_TRAG_CMD_B1,AHT20_TRAG_CMD_B2};
  return AHT20_Write(&startcmd,sizeof(startcmd));  
}

// 读取温湿度值之前， 首先要看状态字的校准使能位Bit[3]是否为 1(通过发送0x71可以获取一个字节的状态字)，
// 如果不为1，要发送0xBE命令(初始化)，此命令参数有两个字节， 第一个字节为0x08，第二个字节为0x00。
uint32_t AHT20_Calibrate(void)
{
    uint32_t retval = 0;
    uint8_t buffer[AHT20_STATUS_RESPONSE_MAX] = { AHT20_STATUS };
    memset(&buffer, 0x0, sizeof(buffer));

    retval = AHT20_Status();
    if (retval != IOT_SUCCESS) {
        return retval;
    }

    retval = AHT20_Read(&buffer, sizeof(buffer));
    if (retval != IOT_SUCCESS) {
        return retval;
    }

    if (AHT20_STATUS_BUSY(buffer[0]) || !AHT20_STATUS_CALI(buffer[0])) {
        retval = AHT20_Reset();
        if (retval != IOT_SUCCESS) {
            return retval;
        }
        usleep(AHT20_WAIT_TIME);
        retval = AHT20_Initcmd();
        usleep(AHT20_WAIT_TIME);
        return retval;
    }
    return IOT_SUCCESS;
}


// 接收测量结果，拼接转换为标准值
uint32_t AHT20_GetMeasureResult(float* temp, float* humi)
{
    uint32_t retval = 0, i = 0;
    if (temp == NULL || humi == NULL) {
        return IOT_FAILURE;
    }

    uint8_t buffer[AHT20_STATUS_RESPONSE_MAX] = { 0 };
    memset(&buffer, 0x0, sizeof(buffer));
    retval = AHT20_Read(buffer, sizeof(buffer));  // recv status command result
    if (retval != IOT_SUCCESS) {
        return retval;
    }

    for (i = 0; AHT20_STATUS_BUSY(buffer[0]) && i < AHT20_MAX_RETRY; i++) {
        // printf("AHT20 device busy, retry %d/%d!\r\n", i, AHT20_MAX_RETRY);
        usleep(AHT20_WAIT_TIME);
        retval = AHT20_Read(buffer, sizeof(buffer));  // recv status command result
        if (retval != IOT_SUCCESS) {
            return retval;
        }
    }
    if (i >= AHT20_MAX_RETRY) {
        printf("AHT20 device always busy!\r\n");
        return IOT_FAILURE;
    }

    uint32_t humiRaw = buffer[1];
    humiRaw = (humiRaw << 8) | buffer[2];
    humiRaw = (humiRaw << 4) | ((buffer[3] & 0xF0) >> 4);
    *humi = humiRaw / (float)AHT20_RESLUTION * 100;

    uint32_t tempRaw = buffer[3] & 0x0F;
    tempRaw = (tempRaw << 8) | buffer[4];
    tempRaw = (tempRaw << 8) | buffer[5];
    *temp = tempRaw / (float)AHT20_RESLUTION * 200 - 50;
    // printf("humi = %05X, %f, temp= %05X, %f\r\n", humiRaw, *humi, tempRaw, *temp);
    return IOT_SUCCESS;
}